# 分页爬取58同城的租房信息，信息内容要求有：【标题、图片、户型、价格】，并且获取指定页的所有租房信息
# 第七周作业2)
# 班级：Python五期
# 学员：李子坚

from requests.exceptions import RequestException
import requests
import re,time,json
import os

def getPage(url):
    '''爬取指定url页面信息'''
    try:
        #定义请求头信息
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'
        }
        #定义数据信息
        data = {
            'ClickID':2,
        }
        # 执行爬取
        res = requests.get(url,params=data,headers=headers)
        
        #判断响应状态,并响应爬取内容
        if res.status_code == 200:
            html = res.content.decode('utf-8')
            return html
        else:
            return None
    except RequestException:
        return None

def parsePage(html):
    '''解析爬取网页中的内容，并返回字段结果'''
    #定义解析正则表达式
    pat = '<div class="img_list">[\s]*<a .*?>[\s]*<img[\s]*lazy_src="(.*?)"[\s]*src=".*?">[\s]*</a>.*?</div>[\s]*<div class="des">[\s]*<h2>[\s]*<a .*?>(.*?)</a>.*?</h2>[\s]*<p class="room">(.*?)</p>.*?<div class="jjr">.*?</div>[\s]*</div>[\s]*<div class="listliright">.*?<div class="money">[\s]*<b>(.*?)</b>(.*?)</div>[\s]*</div>'
    #执行解析
    items = re.findall(pat,html,re.S)
    #遍历封装数据并返回
    for item in items:
        print("{:<42}{:<96}{:<16}{:<12}".format(item[1].strip(),item[0],item[2].strip().replace(" ","").replace("&nbsp;"," "),item[3].strip()+item[4].strip()))
        yield "{},{},{},{}".format(item[1].strip(),item[0],item[2].strip().replace(" ","").replace("&nbsp;"," "),item[3].strip()+item[4].strip())

def writeFile(content):
    '''执行文件追加写操作'''
    #print(content)
    with open("./58rentresult.csv",'a',encoding='utf-8') as f:
        f.write(json.dumps(content,ensure_ascii=False).replace("\"","") + "\n")
        #json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False

def main(page):
    ''' 主程序函数，负责调度执行爬虫处理 '''
    #输出每页标题行
    print("%s%s%d%s%s"%("="*85,"第",page,"页","="*85))
    print("{:<58}{:<94}{:<16}{:<12}".format("标题","图片","户型","价格"))
    url = "http://sz.58.com/qianhai/chuzu/pn%d"%(page)
    html = getPage(url)

    try:
        #判断是否爬取到数据，并调用解析函数
        if html:
            #爬取内容逐行输出到文件
            for item in parsePage(html):
                #逐行输出租房信息
                writeFile(item)
                
    except Exception as e:
        if hasattr(e,'reason'):
            print(e.reason)

        if hasattr(e,'code'):
            print(e.code)


# 判断当前执行是否为主程序运行，并遍历调用主函数爬取数据
if __name__ == '__main__':

    pages_num = int(input("请输入要爬取深圳58同城南山区前海片区租房信息的页数："))
    print("亲，正在爬取深圳58同城南山区前海片区租房信息，请稍候……")
    print("")
    #输出文件标题行
    writeFile("{},{},{},{}".format("标题","图片","户型","价格"))

    #爬取深圳58同城南山区前海片区租房信息
    for i in range(pages_num):
        main(i+1)
        time.sleep(1)

    print("")
    print("==========深圳58同城南山区前海片区租房信息爬取完成！==========")
    print("请查看深圳58同城南山区前海片区租房信息文件<58rentresult.csv>！")
